﻿using System.Threading.Tasks;

namespace ThingsGateway.Foundation
{
    /// <summary>读写网络的辅助类</summary>
    public class ReadWriteHelper
    {

        #region Public Methods

        /// <inheritdoc cref="IReadWrite.Wait(string,bool,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          bool waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<bool> result;
            while (true)
            {
                result = readWriteNet.ReadBool(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,short,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          short waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<short> result;
            while (true)
            {
                result = readWriteNet.ReadInt16(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }

        }

        /// <inheritdoc cref="IReadWrite.Wait(string,ushort,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          ushort waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<ushort> result;
            while (true)
            {
                result = readWriteNet.ReadUInt16(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,int,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          int waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<int> result;
            while (true)
            {
                result = readWriteNet.ReadInt32(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,uint,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          uint waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<uint> result;
            while (true)
            {
                result = readWriteNet.ReadUInt32(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }

        }

        /// <inheritdoc cref="IReadWrite.Wait(string,long,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          long waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<long> result;
            while (true)
            {
                result = readWriteNet.ReadInt64(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }

        }

        /// <inheritdoc cref="IReadWrite.Wait(string,ulong,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static Result<TimeSpan> Wait(
          IReadWrite readWriteNet,
          string address,
          ulong waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<ulong> result;
            while (true)
            {
                result = readWriteNet.ReadUInt64(address);
                if (result.IsSuccess)
                {
                    if (result.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            Thread.Sleep(readInterval);
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return result.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,bool,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          bool waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<bool> read;
            while (true)
            {
                read = await readWriteNet.ReadBoolAsync(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,short,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          short waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<short> read;
            while (true)
            {
                read = await readWriteNet.ReadInt16Async(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,ushort,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          ushort waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<ushort> read;
            while (true)
            {
                read = await readWriteNet.ReadUInt16Async(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,int,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          int waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<int> read;
            while (true)
            {
                read = await readWriteNet.ReadInt32Async(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }

        }

        /// <inheritdoc cref="IReadWrite.Wait(string,uint,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          uint waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<uint> read;
            while (true)
            {
                read = readWriteNet.ReadUInt32(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }
        }

        /// <inheritdoc cref="IReadWrite.Wait(string,long,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          long waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<long> read;
            while (true)
            {
                read = readWriteNet.ReadInt64(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }

        }

        /// <inheritdoc cref="IReadWrite.Wait(string,ulong,int,int)" />
        /// <param name="readWriteNet">通信对象</param>
        public static async Task<Result<TimeSpan>> WaitAsync(
          IReadWrite readWriteNet,
          string address,
          ulong waitValue,
          int readInterval,
          int waitTimeout)
        {
            DateTime now = DateTime.Now;
            Result<ulong> read;
            while (true)
            {
                read = readWriteNet.ReadUInt64(address);
                if (read.IsSuccess)
                {
                    if (read.Content != waitValue)
                    {
                        if (waitTimeout <= 0 || (DateTime.Now - now).TotalMilliseconds <= waitTimeout)
                        {
                            await Task.Delay(readInterval);
                            read = null;
                        }
                        else
                        {
                            return new Result<TimeSpan>(ThingsGateway.Foundation.Resources.Resource.CheckDataTimeout + waitTimeout.ToString());
                        }
                    }
                    else
                    {
                        return Result.CreateSuccessResult(DateTime.Now - now);
                    }
                }
                else
                {
                    return read.Copy<TimeSpan>();
                }
            }

        }

        #endregion Public Methods

    }
}